-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[experimental feature] Support HOAS pattern with type variables for quote pattern matching #18271
Conversation
988087c
to
6b345cc
Compare
282e4ad
to
fc15089
Compare
* (NOTE: Needs non-trivial extension to type system) | ||
*/ | ||
val bounds = ctx.gadt.fullBounds(typedTypearg.symbol) | ||
if bounds != null && bounds != TypeBounds.empty then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We might want to move this logic to checkPattern
because we have fully-typed tree.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sync Aug 07: How to check type bounds with fully typed tree?
49c0cca
to
6764d5e
Compare
* (NOTE: Needs non-trivial extension to type system) | ||
*/ | ||
val bounds = ctx.gadt.fullBounds(typedTypearg.symbol) | ||
if bounds != null && bounds != TypeBounds.empty then |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sync Aug 07: How to check type bounds with fully typed tree?
dc7be2b
to
f8764b6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Add comment with "Implementation restriction"
- Add test cases with and without experimental flags
- (potentailly) improve performance of type comparison under an environment
- update stdlibExperimentalDefinitions.scala
- Add documentation
body match | ||
case '{ [A] => (x : A) => $b[A] : (A => A) } => // error | ||
Expr("A higher-order pattern must carry value params") | ||
case '{ [A] => (x : A) => $b(x) : (A => A) } => // error |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
better to have: Show example of expected code $b[A](x)
in this case
3b44c95
to
61f4b7f
Compare
11fdce9
to
ab8a613
Compare
I will rebase this PR to solve the small conflict in |
e53c7e6
to
02b60bf
Compare
Future proof for scala#18271.
Future proof for scala#18271.
This has been decided to be included in 3.6.0. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rebased to resolve conflicts (all very simple). Also added some (also very simple) changes to make it work on top of #17396
@@ -0,0 +1,5 @@ | |||
//> using options -experimental |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added experimental
here and in other tests
assert(targs.isEmpty, "unexpected type arguments in SPLICEPATTERN") // `targs` will be needed for #18271. Until this fearure is added they should be empty. | ||
SplicePattern(pat, args, patType) | ||
SplicePattern(pat, targs, args, patType) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Adjusted pickling and unpicking of SplicePatterns as it was previously prepared for this PR by Nicolas
case SplicePattern(pat, args) => | ||
val targs = Nil // SplicePattern `targs` will be added with #18271 | ||
case SplicePattern(pat, targs, args) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same here
Thank you so much @zeptometer! Fantastic work! |
@jchyb I'm glad to hear that this feature is merged 😄 Thank you for your effort in merging this PR! |
This PR extends higher-order patterns inside quote patterns to allow type parameters. When this PR is merged, we'll be able to write quote patterns like the following example with an experimental flag
experimental.quotedPatternsWithPolymorphicFunctions
.You can see that the higher-order pattern
$y[A](x)
carries an type parameterA
. It states that this pattern matches a code fragment with occurrences ofA
, andy
is assigned a polymorphic function type[A] => List[A] => x
.This PR mainly changes two parts: type checker and quote pattern matcher. Those changes are based on the formalized type system defined in Nicolas Stucki's thesis, and one can expect the soundness of the implementation.
Type Dependency
If a higher-order pattern carries a value parameter with a type that has type parameters defined in the quoted pattern, those type parameters should also be captured in the higher-order pattern. For example, the following pattern will not be typed.
In this case,
x
has the typeList[A]
, which includes a type variableA
that is defined in the pattern. However, the higher-order pattern$y(x)
does not have any type parameters. This should be ill-typed. One can always avoid this kind of type errors by adding type parameters, like$y[A](x)
Implementation Restriction
Current implementation only allows type parameters that do not have bounds, because sound typing rules for such pattern is not clear yet.